import { EChartsInstance } from "echarts-for-react";

export interface IKeyValuePair {
  [key: string]: any
}

/**
 * 图例更新模块接口
 */
export interface ILegendUpdater {
  /**
   * 添加 chart 实例
   */
  addCharts: (charts: EChartsInstance) => void
  /**
   * 移除 chart 实例
   */
  removeCharts: (charts: EChartsInstance) => void
  /**
   * 开始更新
   */
  start: () => void
  /**
   * 暂停更新
   */
  stop: () => void
  /**
   * 重置循环状态
   */
  reset: () => void
}

/**
 * echarts 图例自动更新模块
 * @param interval 轮播间隔
 * @returns 
 */
function LegendUpdater(interval: number = 5000): ILegendUpdater {
  // 缓存的 echarts 实例
  const cachedCharts: Set<EChartsInstance> = new Set();

  // 数组索引
  let index = 0;

  // 定时器
  let timer: number = -1;

  function addCharts(charts: EChartsInstance) {
    if (!Array.isArray(charts) || !charts.length) {
      return;
    }

    charts.forEach((chart) => {
      init(chart);
      cachedCharts.add(chart);
    });
  }

  function removeCharts(charts: EChartsInstance) {
    if (!Array.isArray(charts) || !charts.length) {
      return;
    }

    charts.forEach((chart) => {
      cachedCharts.delete(chart);
    });

  }

  /**
   * 初始化
   */
  function init(instance: EChartsInstance) {
    const option = instance.getOption();
    const {
      legend: [{ data }],
    } = option;
    const selected: IKeyValuePair = {};
    data.forEach((legendItem: string, index: number) => {
      if (index === 0) {
        selected[legendItem] = true;
        return
      }
      selected[legendItem] = false;
    });
    instance.setOption({ legend: { selected } });
  }

  /**
   * 开始更新
   * @param {number} interval 间隔
   */
  function start() {
    if (timer !== -1) {
      return;
    }
    update();
  }

  function update() {
    cachedCharts.forEach((instance) => {
      const option = instance.getOption();
      const {
        legend: [{ data }],
      } = option;
      const selected: IKeyValuePair = {};
      const { length } = data;
      const targetIndex = index % length;
      data.forEach((legendItem: string, index: number) => {
        selected[legendItem] = targetIndex === index;
      });
      instance.setOption({ legend: { selected } });
    });
    index++;
    timer = setTimeout(() => {
      update();
    }, interval) as any;
  }

  /**
   * 暂停更新
   */
  function stop() {
    if (timer !== -1) {
      clearTimeout(timer);
      timer = -1;
    }
  }

  /**
   * 重置更新器
   */
  function reset() {
    stop();
    index = 0;
  }

  return {
    addCharts,
    removeCharts,
    start,
    stop,
    reset,
  };
}

export default LegendUpdater
